package com.aocore.proxy;

import com.aocore.AoCoreProperties;
import com.aocore.packet.Packet;
import com.aocore.packet.RC.RealmStartupRequest;
import com.aocore.packet.RCPacket;
import com.aocore.packet.RS.JoinGameResponse;
import com.aocore.packet.RSPacket;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

/**
 *
 * @author derek
 */
public final class RealmProxy extends Proxy
{
    private boolean magic = true;

    public RealmProxy(SocketChannel socketChannel) throws IOException
    {
        super(socketChannel);
        System.out.println("NEW REALM PROXY");
    }

    public void writePacket(RSPacket packet) throws IOException
    {
        writeServerPacket(packet);
    }

    public void writePacket(RCPacket packet) throws IOException
    {
        writeClientPacket(packet);
    }

    @Override
    protected List<Packet> parseClientPacket(ByteBuffer byteBuffer)
    {
        List<Packet> packets = new LinkedList<Packet>();

        while (true)
        {
            if (magic)
            {
                byte[] data = new byte[1];

                byteBuffer.flip();
                byteBuffer.get(data);
                byteBuffer.compact();

                Packet packet = new com.aocore.packet.RC.Invalid(data);
                packets.add(packet);

                magic = false;
                continue;
            }

            if (byteBuffer.position() < 2)
            {
                break;
            }

            int packet_length = byteBuffer.getShort(0);

            if (packet_length > byteBuffer.position())
            {
                break;
            }

            byte[] data = new byte[packet_length];

            byteBuffer.flip();
            byteBuffer.get(data);
            byteBuffer.compact();

            Packet packet = RCPacket.create(data);
            packets.add(packet);
        }

        return packets;
    }

    @Override
    protected List<Packet> parseServerPacket(ByteBuffer byteBuffer)
    {
        List<Packet> packets = new LinkedList<Packet>();

        while (true)
        {
            if (byteBuffer.position() < 2)
            {
                break;
            }

            int packet_length = byteBuffer.getShort(0);

            if (packet_length > byteBuffer.position())
            {
                break;
            }

            byte[] data = new byte[packet_length];

            byteBuffer.flip();
            byteBuffer.get(data);
            byteBuffer.compact();

            Packet packet = RSPacket.create(data);
            packets.add(packet);
        }

        return packets;
    }

    @Override
    protected Packet processClientPacket(Packet packet)
    {
        if (packet instanceof RealmStartupRequest)
        {
            RealmStartupRequest realmStartupRequest = (RealmStartupRequest) packet;
            awesomO = bots.get(Arrays.hashCode(realmStartupRequest.getHash()));
            awesomO.setRealmProxy(this);

            try
            {
                connectClient(awesomO.getRealmAddress());
            }
            catch (IOException e)
            {
                e.printStackTrace(System.err);
                stopProxy();
            }
        }

        return packet;
    }

    @Override
    protected Packet processServerPacket(Packet packet)
    {
        if (packet instanceof JoinGameResponse)
        {
            JoinGameResponse joinGameResponse = (JoinGameResponse) packet;
            try
            {
                InetSocketAddress address = new InetSocketAddress(InetAddress.getByAddress(joinGameResponse.getIp()), AoCoreProperties.GAME_PORT);
                awesomO.setGameAddress(address);
                bots.put(Arrays.hashCode(joinGameResponse.getHash()), awesomO);

                System.err.println("hash: " + Arrays.hashCode(joinGameResponse.getHash()));
                System.err.println("ip: " + address.getHostName());
            }
            catch (UnknownHostException e)
            {
                e.printStackTrace(System.err);
                stopProxy();
            }
        }

        return packet;
    }
}
